package main

import (
	"fmt"
	"sync"
)

/*
WaitGroup 类似一个计数器，用来追踪一组正在执行的任务；
每启动一个任务（通常是 goroutine），就调用 Add(1) 增加计数；
当某个任务完成后，调用 Done() 减少计数；
主 goroutine 调用 Wait() 阻塞自己，直到计数归零，表示所有任务完成。
相当于java的CountDownLatch
*/

/*
使用方法

声明 WaitGroup
var wg sync.WaitGroup

添加等待任务数
wg.Add(n) // n 是要等待的 goroutine 数量

每个 goroutine 结束时调用 Done()
defer wg.Done()

主 goroutine 调用 Wait() 等待完成
wg.Wait()
*/
func main() {
	var wg sync.WaitGroup
	ch := make(chan int)

	var started sync.WaitGroup
	started.Add(1)

	// receive goroutine
	go func() {
		started.Wait() // 等待 send 启动后再开始接收
		for i := range ch {
			fmt.Printf("接收到: %d\n", i)
		}
	}()

	// send goroutine
	wg.Add(1)
	go func() {
		defer wg.Done()
		started.Done() // 通知 receive 可以开始了
		for i := 0; i < 5; i++ {
			ch <- i
			fmt.Printf("send: %d\n", i)
		}
		close(ch)
	}()

	wg.Wait()
	fmt.Println("main 结束")
}
